Simple application Node.js + Koa

Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs.
Through leveraging generators Koa allows you to ditch callbacks and greatly increase error-handling. Koa does not bundle any middleware within core, and provides an elegant suite of methods that make writing servers fast and enjoyable.

Let’s create a simple Koa application, and review some useful middlewares for it.

Requirements

Koa requires Node 7.6.0 or higher for async/await syntax.
You can use older Node versions with Babel (see more about it at Koa installation section).

Environment

Node.js

If Node is not installed yet, you can download it here. If you are a lucky owner of Linux or macOS, package managers can be used - this method described here.
To check that the Node installation is correct, you can run the command:

1
$ node --version

That will print the Node version.
Also for NPM:
Also don’t forget about NPM (Node Package Manager):

1
$ npm --version

You can use NVM (Node Version Manager) and if you know what it is, it shouldn’t be a problem.

Dependencies installation

Create directory where all the code will be located. Run terminal and open this directory.

Let’s initialize the package environment. This, at a minimum, will help us keep the list of dependencies with our code, and as a maximum - create a great package for distribution to the community.

1
$ npm init

NPM will ask you a few questions. Type answers for package name of author.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (ex) koa-simple-app
version: (1.0.0)
description: Koa simple application
entry point: (index.js)
test command:
git repository:
keywords:
author: Nariman Safiulin <woofilee@gmail.com>
license: (ISC)
About to write to <..>\package.json:

{
"name": "koa-simple-app",
"version": "1.0.0",
"description": "Koa simple application",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Nariman Safiulin <woofilee@gmail.com>",
"license": "ISC"
}


Is this ok? (yes)

You should see the package.json file that NPM has created.

Install koa:

1
$ npm i koa

Hello, World!

Let’s create a file index.js, and copy-paste the next slightly modified version of standard Koa example.

1
2
3
4
5
6
7
8
9
10
11
const Koa = require('koa');

const app = new Koa();

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Code is simple to understand.
We’ve created a Koa application instance. With a use method you can add a middleware to the chain. All middlewares will be executed in sequence with each request. Each middleware accepts two arguments - ctx and next, where ctx is a request context (obviously), and next - the next middleware in the chain. In the last middleware the next argument can be omitted (as in example).
After that we’ve tell Koa to listen the port 3000. Callback allows us to understand that the server actually started, rather than hangs.

Now we can start the server:

1
$ node index.js

If the server has successfully started, open the browser and go to localhost:3000. You should see the Hello, World! page.

You can read more about Koa functionality on the Koa website.

Useful stuff

You can find alternatives for every middleware in the next list, as well as other middlewares.

Koa-router

The library allows you to get the necessary functionality of routing requests to different handlers. Without this middleware, it’s not very possible to do something more than Hello, World!.
In addition to koa-router, there are a lot of other analogues, for example, a simpler [koa-route] (https://github.com/koajs/route), which is difficult to come up with any application for ambitious purposes, and a router with data validation of incoming and outgoing data in requests/reponses [joi-router] (https://github.com/koajs/joi-router). Nevertheless, koa-router is the most popular at the moment, and it has balanced functionality, nothing superfluous.

1
$ npm i koa-router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Koa = require('koa');
const Router = require('koa-router'); // Changed

const app = new Koa();
const router = new Router(); // Router initialization

router.get('/', (ctx, next) => { // We will handle GET requests
ctx.body = 'Hello, World!';
});

app.use(router.routes()).use(router.allowedMethods()); // Add routes to the middleware chain, and respond to the OPTIONS requests.

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Read more about koa-router here.

Koa-bodyparser

Koa out of the box doesn’t know how to parse some data in requests.
If we need to accept requests with a JSON body, for example, then this middleware is necessary.

1
$ npm i koa-bodyparser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const Koa = require('koa');
const BodyParser = require('koa-bodyparser'); // Changed

const app = new Koa();

app.use(bodyParser()); // Use Parser before the route handler

app.use(async ctx => {
// Parsed data is located in ctx.request.body
// Empty object as a placeholer will be used if there is nothing to parse
ctx.body = ctx.request.body;
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

More about koa-bodyparser is here.

Koa-logger

Logs of what requested, and what responded, are also needed. For development, the koa-logger can be used.
It will look something like this (taken from the page of the package):

1
2
3
4
5
6
7
8
<-- GET /
--> GET / 200 835ms 746b
<-- GET /
--> GET / 200 960ms 1.9kb
<-- GET /users
--> GET /users 200 357ms 922b
<-- GET /users?page=2
--> GET /users?page=2 200 466ms 4.66kb

Very simple. If you want more information about requests, you can try [bunyan-logger] (https://github.com/koajs/bunyan-logger).

1
$ npm i koa-logger
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Koa = require('koa');
const Logger = require('koa-logger'); // Changed

const app = new Koa();

app.use(Logger()); // Logger is before the route handler

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Repository of koa-logger is located here.

@koa/cors

CORS requests sometimes are needed.

1
$ npm i @koa/cors@2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Koa = require('koa');
const CORS = require('@koa/cors'); // Changed

const app = new Koa();

app.use(CORS()); // Before the route handler!

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Repository of @koa/cors is here.

Koa-compress

Compress responses from the server.

1
$ npm i koa-compress
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const Koa = require('koa');
const Compress = require('koa-compress'); // Changed

const app = new Koa();

app.use(Compress({
filter: function (content_type) {
return /text/i.test(content_type)
},
threshold: 2048,
flush: require('zlib').Z_SYNC_FLUSH
})); // Before the route handler! We'll compress any text responses.

app.use(async ctx => {
ctx.body = 'Hello, World!';
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Read more about koa-compress here.

Koa-session

If cookie sessions are required, then this is a good package.

1
$ npm i koa-session
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const Koa = require('koa');
const Session = require('koa-session'); // Changed

const app = new Koa();

app.keys = ['secret key']; // We need some random bytes to sign our cookie session

app.use(Session(app)); // All options by default

app.use(async ctx => {
// Let's count the number of Hello, World! page views.
// Don't forget about the fact, that the browser will ask a favicon, that's why the number can be increased by 2.
let n = ctx.session.views || 0;
ctx.session.views = ++n;
ctx.body = `Hello, World! x${n}`;
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

More koa-session options is here.

Koa-JWT

And JWT, of course. Very useful for API development. It’s a little difficult to come up with a simple example using this library, so you can read README in the package repository.

1
$ npm i koa-jwt

Read more about koa-jwt here.

In conclusion

Koa performs its only important function - to accept requests to the server, and apply a middleware chain to them. This allows you to achieve good flexibility in the development of the application, and to use only what is needed.
It’s also very similar to [Express] (https://expressjs.com/).
So there should not be any problems with it.